package sim16;
/**
 * 
 */
import java.io.*;
import java.util.Scanner;
import java.util.TreeMap;

/**
 * The data memory class.
 * @author Piotr
 *
 */
public class DataMemory {
	private TreeMap<Integer, Integer> dmem;
	
	/**
	 * Creates a new DataMemory and leaves it blank.
	 */
	DataMemory() {
		dmem = new TreeMap<Integer, Integer>();
	}
	
	/**
	 * Creates a new DataMemory and fills it using the initData file.
	 * @param initData	file containing the program.
	 * @throws FileNotFoundException 
	 */
	DataMemory(File initData) throws FileNotFoundException {
		Scanner scin = new Scanner(initData);
		Scanner scline;
		String line;
		dmem = new TreeMap<Integer, Integer>();
		int address;
		int data;
		while (scin.hasNext()) {			// Add some safety checks here
			line = scin.nextLine();
			scline = new Scanner(line);
			String temp = scline.findInLine("^#\\d+");
			if (temp != null) {
				address = new Integer(temp.substring(1, temp.length()));
				if (scline.hasNextInt()) {
					data = scline.nextInt(10);
					
					if (!dmem.containsKey(address)) {
						dmem.put(address, data);
					} else {
						System.out.println("Error, repeat addresses in data initialization file: " + address);
						
					}
				}
			}
			
		}
	}
	
	/**
	 * Returns the data at the given address, 0 if the address has not been initialized.
	 * @param address of the desired memory location
	 * @return The data at address
	 */
	int read(int address) {
		if (dmem.containsKey(address)) {
			int value = dmem.get(address);
			return value;
		} else {
			return 0;
		}
	}
	
	void write(int address, int data) {
		dmem.put(address, data);
	}
	
	/**
	 * Returns the highest key (address) in the instruction memory. 
	 * @return The last address in the instruction memory with an instruction.
	 */
	int getHighestAddress() {
		return dmem.lastKey();
	}
	
	/**
	 * Returns a memory dump of all altered memory cells.
	 */
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("######################### Memory Dump #########################");
		sb.append("\nAddress\t\tValue");
		for(Integer key: dmem.navigableKeySet()) {
			sb.append("\n#" + key + "\t\t" + dmem.get(key));
		}
		sb.append("\n");
		return sb.toString();
	}

}
